package com.zeny.coding.controller.admin.file;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import com.aliyuncs.vod.model.v20170321.GetMezzanineInfoResponse;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;

import com.zeny.coding.config.VodConfig;
import com.zeny.coding.dto.FileDto;
import com.zeny.coding.dto.Response;
import com.zeny.coding.enmus.FileUseEnum;
import com.zeny.coding.service.FileService;
import com.zeny.coding.util.Base64ToMultipartFile;
import com.zeny.coding.util.VodUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

@SuppressWarnings("all")
@Slf4j
@RestController
@RequestMapping("/file/admin")
public class VodController {

    @Autowired
    private VodConfig vodConfig;

    public static final String BUSINESS_NAME = "VOD上传";

    @Resource
    private FileService fileService;

    /**
     * <h2>阿里云视频点播上传</h2>
     **/
    @PostMapping("/vod")
    public Response fileUpload(@RequestBody FileDto fileDto) throws Exception {
        log.info("上传文件开始");
        //视频用途 教师 | 课程
        String use = fileDto.getUse();
        //文件唯一标识
        String key = fileDto.getKey();
        //文件后缀
        String suffix = fileDto.getSuffix();
        //文件上传分片，因为视频点播只能单文件上传，所有只有一个分片
        Integer shardIndex = fileDto.getShardIndex();
        //文件分片大小
        Integer shardSize = fileDto.getShardSize();
        //文件的base64字符串
        String shardBase64 = fileDto.getShard();
        //件的base64字符串转文件
        MultipartFile shard = Base64ToMultipartFile.base64ToMultipart(shardBase64);
        //根据文件用途获取文件夹
        FileUseEnum useEnum = FileUseEnum.getByCode(use);
        String dir = useEnum.name().toLowerCase();
        //String path = dir + File.separator + key + "." + suffix + "." + fileDto.getShardIndex();
        String path = new StringBuffer(dir)
                .append("/")
                .append(key)
                .append(".")
                .append(suffix)
                .toString();
        String vod = "";
        //视频播放路径
        String fileUrl = "";
        try {
            // 初始化VOD客户端并获取上传地址和凭证
            DefaultAcsClient vodClient = VodUtil.initVodClient(vodConfig.getAccessKeyId(),
                    vodConfig.getAccessKeySecret());
            CreateUploadVideoResponse createUploadVideoResponse = VodUtil.createUploadVideo(vodClient, path);
            // 执行成功会返回VideoId、UploadAddress和UploadAuth
            vod = createUploadVideoResponse.getVideoId();
            JSONObject uploadAuth = JSONObject.parseObject(
                    Base64.decodeBase64(createUploadVideoResponse.getUploadAuth()), JSONObject.class);
            JSONObject uploadAddress = JSONObject.parseObject(
                    Base64.decodeBase64(createUploadVideoResponse.getUploadAddress()), JSONObject.class);
            // 使用UploadAuth和UploadAddress初始化OSS客户端
            OSSClient ossClient = VodUtil.initOssClient(uploadAuth, uploadAddress);
            // 上传文件，注意是同步上传会阻塞等待，耗时与文件大小和网络上行带宽有关
            VodUtil.uploadLocalFile(ossClient, uploadAddress, shard.getInputStream());
            log.info("上传视频成功, vod : {}", vod);
            GetMezzanineInfoResponse response = VodUtil.getMezzanineInfo(vodClient, vod);
            log.info("获取视频信息, response : {}", JSON.toJSONString(response));
            fileUrl = response.getMezzanine().getFileURL();
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传视频失败, ErrorMessage : {}", e);
        }
        log.info("保存文件记录开始");
        fileDto.setPath(path);
        //保存视频的VideoId
        fileDto.setVod(vod);
        fileService.save(fileDto);
        fileDto.setPath(fileUrl);
        return new Response().success().data(fileDto);
    }

    /**
     * <h2>根据videoId获取视频点播的播放凭证</h2>
     * @param vod
     **/
    @GetMapping("/get-auth/{vod}")
    public Response getAuth(@PathVariable("vod") String vod) throws ClientException {
        log.info("获取播放授权开始: ");
        DefaultAcsClient client = VodUtil.initVodClient(vodConfig.getAccessKeyId(), vodConfig.getAccessKeySecret());
        GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();
        try {
            response = VodUtil.getVideoPlayAuth(client, vod);
            log.info("授权码 = {}", response.getPlayAuth());
            //VideoMeta信息
            log.info("VideoMeta = {}", JSON.toJSONString(response.getVideoMeta()));
        } catch (Exception e) {
            log.error("ErrorMessage = {}" + e.getLocalizedMessage());
        }
        log.info("获取播放授权结束");
        return new Response().success().data(response.getPlayAuth());
    }
}
